/*
 * Copyright (c) 2025 Huawei Technologies Co., Ltd.
 * openUBMC is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *         http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
#ifndef DEVMON_DEVICE_DRIVER_H
#define DEVMON_DEVICE_DRIVER_H

#include "devmon/driver_abi.h"

#include <memory>
#include <string>
#include <unordered_map>
#include <vector>
#include <chrono>
#include <fstream>

namespace devmon {

struct driver_load_info {
    std::string driver_name;    // 驱动库名称
    bool        success;        // 是否加载成功
    double      load_time_ms;   // 加载耗时（毫秒）
    size_t      device_count;   // 加载设备数量
    std::string error_msg;      // 错误信息
};


using device_drivers = std::vector<std::shared_ptr<device_driver_t>>;
class device_driver {
public:
    device_driver(const std::string& driver_name);
    ~device_driver() = default;

    void load(const std::string& driver_path);
    void unload();

    device_driver_t&      get_device(std::string& device_name);
    const device_drivers& get_devices() const;
    // 用于DT测试
    void             set_device_driver(device_drivers* device_driver);
    std::string_view get_name();

private:
    void register_driver();

private:
    device_drivers m_devices;
    std::string    m_driver_name;
    void*          m_driver_handle{nullptr};

public:
    static std::vector<driver_load_info> s_load_info_table;
};

class device_driver_factory {
public:
    static device_driver_factory& get_instance();
    device_driver&                get_device_driver(const std::string& driver_name);
    void                          set_driver_path(const std::string& driver_path);

    // 用于DT测试
    void set_device_driver(const std::string& driver_name, device_drivers* device_driver);
    void remove_device_driver(const std::string& driver_name);

private:
    device_driver_factory()  = default;
    ~device_driver_factory() = default;

    using driver_ptr = std::shared_ptr<device_driver>;
    using driver_map = std::unordered_map<std::string, driver_ptr>;

    driver_map  m_drivers;
    std::string m_driver_path;
};

} // namespace devmon

#endif // DEVMON_DEVICE_DRIVER_H